import store from "@/store"

const baseUrl = 'http://smart-shop.itheima.net/index.php?s=/api/'
const DEFAULT_REQUEST_TIMEOUT = 1000 * 10

enum RequestMethod {
    GET = 'GET',
    POST = 'POST',
}

interface Params {
    [key: string]: string | number | boolean;
}

interface RequestOptions {
    url: string
    method: RequestMethod
    data?: any
    headers?: any
    timeout: number
}

interface RequestRunner extends RequestOptions {
    success: (response: any) => void
    fail: (error: any) => void
}

interface ResponseResult<T=unknown> {
    status: number,
    message: string,
    data: T,
}


function pathJoin(...args: string[]): string {
    if (args.length === 0) {
        return ''
    }
    var res = args[0]
    for (var i = 1; i < args.length; i++) {
        if(res.endsWith('/') && args[i].startsWith('/')) {
            res += args[i].slice(1)
        } else if (!res.endsWith('/') &&!args[i].startsWith('/')) {
            res += '/' + args[i]
        } else {
            res += args[i]
        }
    }
    return res
}

/**
 * 请求拦截器
 * @param request 请求参数
 */
function requestInterceptor(request: RequestOptions): void {

    // 只要有token就在请求时携带,便于请求需要授权的接口
    const token = store.state.user.userInfo.token
    if (token) {
        // request.headers['Access-Token'] = token
        request.headers = {
            ...request.headers,
            'Access-Token': token,
        }
    }
    // request.headers['platform'] = uni.getSystemInfoSync().platform
    request.headers = {
        ...request.headers,
         platform: uni.getSystemInfoSync().platform,
    }

    uni.showLoading({
        title: '加载中。。。',
        mask: true,  // 禁止背景点击
    })
}

/**
 * 响应拦截器-请求成功
 * @param response 响应参数
 */
function successCallback(response: UniApp.RequestSuccessCallbackResult): any {
    var res: ResponseResult = response.data as ResponseResult
    if (res.status !== 200) {
        // 给提示
        // Toast(res.message)
        uni.showToast({
            title: '请求失败',
            icon: 'error',
            mask: true,  // 显示透明蒙层，防止用户点击其他位置
            duration: 2000  // 提示时长
        })
        // 抛出一个错误的promise
        return Promise.reject(res.message)
      } else {
        // Toast.clear()
        uni.hideLoading()
      }
      return res
}

/**
 * 响应拦截器-请求失败
 * @param error 错误参数
 */
function failCallback(error: UniApp.GeneralCallbackResult): any {
    return Promise.reject(error)
}

/**
 * 请求完成回调
*/
function completeCallback(): any {
    // 清除加载提示
    uni.hideLoading()
}

const request = {
    $fetch(path: string, method: RequestMethod, data?: Object): Promise<any> {
        var url = pathJoin(baseUrl, path)
        var request: RequestOptions = {
            url: url,
            method: method,
            data: data,
            timeout: DEFAULT_REQUEST_TIMEOUT,
        }
    
        requestInterceptor(request)
    
        return new Promise((resolve, reject) => {
            var runner: RequestRunner = {
                ...request,
                 success: (response) => {
                     resolve(successCallback(response))
                 },
                 fail: (error) => {
                     reject(failCallback(error))
                 },
            }
            uni.request(runner)
        })
    },

    get(path: string, params?: Params) {
        var requestPath = path;
        let paramsStrList: string[] = ['']
        if (params) {
            for (let key in params) {
                if (params.hasOwnProperty(key)) {
                    if (params[key] == null) {
                        continue;
                    }
                    paramsStrList.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
                }
            }
            requestPath += paramsStrList.join('&');
        }
        
        return this.$fetch(requestPath, RequestMethod.GET)
    },

    post(path: string, data: any) {
        return this.$fetch(path, RequestMethod.POST, data)
    }
}

export default request